package com.itfreer.bpm.workflow.service;

import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.itfreer.bpm.config.entity.BpmConfigEntity;
import com.itfreer.bpm.config.entity.BpmTaskConfigEntity;
import com.itfreer.bpm.config.service.IBpmConfigService;
import com.itfreer.bpm.config.service.IBpmTaskConfigService;
import com.itfreer.bpm.flow.api.IBpmProjectEntity;
import com.itfreer.bpm.flow.api.IBpmWorkFlowService;
import com.itfreer.bpm.flow.api.IUserNextTaskUser;
import com.itfreer.bpm.flow.findwork.para.FindWorkInfo;
import com.itfreer.bpm.history.dao.IBpmHistoryDao;
import com.itfreer.bpm.history.entity.BpmHistoryEntity;
import com.itfreer.bpm.messager.BpmMessage;
import com.itfreer.bpm.option.para.OptionInfo;
import com.itfreer.bpm.option.para.TaskInfo;
import com.itfreer.bpm.power.para.UserInfo;
import com.itfreer.bpm.workflow.drive.IWorkFlowDrive;
import com.itfreer.bpm.workflow.option.SignCommonTask;
import com.itfreer.bpm.workflow.option.SignMultiTask;
import com.itfreer.bpm.workflow.service.back.BpmWorkFlowBackImp;
import com.itfreer.bpm.workflow.service.disposal.BpmWorkFlowDisposeImp;
import com.itfreer.bpm.workflow.service.pass.BpmWorkFlowPassImp;
import com.itfreer.bpm.workflow.service.skip.BpmWorkFlowSkipImp;
import com.itfreer.bpm.workflow.userrole.IUserRole;
import com.itfreer.bpm.workflow.utils.BpmApprovalHistoryUtil;
import com.itfreer.bpm.workflow.utils.BpmHistoryEditUtil;
import com.itfreer.bpm.workflow.utils.BpmHistoryQueryUtil;
import com.itfreer.bpm.workflow.utils.BpmNextTaskUtils;
import com.itfreer.bpm.workflow.utils.BpmUserAuthUtils;
/**
 * 平台流程逻辑处理类
 * @author gj
 *
 * @param <T> 项目实体
 */
@Component("BpmWorkFlowServiceImp")
public class BpmWorkFlowServiceImp<T extends IBpmProjectEntity> implements IBpmWorkFlowService{
	
	@Autowired
	private IBpmConfigService bpmConfigService;
	
	@Autowired
	private IBpmTaskConfigService bpmTaskConfigService;
	
	/**
	 * 流程驱动服务
	 */
	@Autowired
	protected IWorkFlowDrive workFlowDrive;
	
	/**
	 * 构建历史帮转工具
	 */
	@Autowired
	BpmHistoryEditUtil historyEditUtl;
	
	/**
	 * 构建用户审批历史
	 */
	@Autowired
	BpmApprovalHistoryUtil approvalUtil;
	
	/**
	 * 用户授权工具
	 */
	@Autowired
	BpmUserAuthUtils userAuthUtils;
	
	/**
	 * 审批过程查询接口
	 */
	@Autowired
	BpmHistoryQueryUtil historyQueryUtil;
	
	/**
	 * 用户角色接口
	 */
	@Autowired
	IUserRole userRole;
	/**
	 * 用户自定义操作下一步审批人接口
	 */
	@Autowired(required=false)
	IUserNextTaskUser userNextTaskUser;
	
	/**
	 * 下一个环节工具
	 */
	@Autowired
	BpmNextTaskUtils nextTaskUtils;
	
	/**
	 * 单节点会签提交
	 */
	@Autowired
	SignMultiTask signmultiTask;
	
	/**
	 * 多节点选择节点
	 */
	@Autowired
	SignCommonTask signCommonTask;
	
	/**
	 * 流程通过实现
	 */
	@Autowired
	BpmWorkFlowPassImp passWorkFlow;
	
	/**
	 * 流程退回实现
	 */
	@Autowired
	BpmWorkFlowBackImp backWorkFlow;
	
	/**
	 * 流程跳转实现
	 */
	@Autowired
	BpmWorkFlowSkipImp skipWorkFlow;
	
	/**
	 * 流程退件实现
	 */
	@Autowired
	BpmWorkFlowDisposeImp disposeWorkFlow;
	
	/**
	 * 办理过程的数据访问层
	 */
	@Autowired
	protected IBpmHistoryDao historyDao;
	
	/**
	 * 找到项目记录
	 * 如果没有，将项目列入初始化配置提交
	 */
	@Override
	public void findWork(FindWorkInfo info, UserInfo user) {
		String sexeid=info.getSexeid();
		String bpmKey=info.getBpmKey();
		String id=info.getId();
		
		String cTaskId="";
		String cTaskName="";
		//0、查询流程配置信息
		HashMap<String,Object> config_where=new HashMap<String,Object>();
		config_where.put("actdefid:=", bpmKey);
		List<BpmConfigEntity> configs=bpmConfigService.getEntitys(null, config_where, null, 1, 1);
		if(configs!=null && configs.size()>0) {
			info.setFormName(configs.get(0).getPrjforname());
			info.setViewId(configs.get(0).getPrjvi());
			
		}
		//1、流程没有启动的项目(两种类型，1-a,项目已经保存，在待办表里面，1-b项目没有保存)
		if(sexeid==null || "".equals(sexeid)) {
			userAuthUtils.setWrokTaskAuth(info, bpmKey,"U0",null);
			//this.workFlowDrive.getCurrentTask(sexeid)
			//TODO 设置当前环节问题
			TaskInfo iTask=this.workFlowDrive.getFirstTask(bpmKey);
			if(iTask!=null) {
				cTaskId=iTask.getTaskdefinedid();
				cTaskName=iTask.getTaskName();
			}
		//2、流程已经启动了，项目处理
		}else {
			//构建审批历史
			approvalUtil.setTaskHisoty(info, sexeid,user);
			
			//3、当前用户的办理情况
			HashMap<String,Object> work_where=new HashMap<String,Object>();
			work_where.put("sexeid:=", sexeid);
			//检查校验是否是超级管理员
			if(!user.isSuperAdmin()) {
				work_where.put("toptassigneese:like",user.getUserId());
			}
			List<BpmHistoryEntity>toWorkList= historyQueryUtil.getWorkEntitys(null, work_where, null, 1000, 1);
			if(toWorkList!=null && toWorkList.size()>0) {
				for(BpmHistoryEntity iWork:toWorkList) {
					userAuthUtils.setWrokTaskAuth(info, bpmKey,iWork.gettaskdefid(),iWork.getTaskstatus());
					
					iWork.setSread("1");
					if("".equals(cTaskId)) {
						cTaskId=iWork.gettaskdefid();
						cTaskName=iWork.gettaskdefname();
					}else {
						cTaskId=cTaskId+","+iWork.gettaskdefid();
						cTaskName=cTaskName+","+iWork.gettaskdefname();
					}
				}
				//保存项目为已经读取的项目
				historyEditUtl.updateList(toWorkList);
			}else {
				if(work_where.containsKey("toptassigneese:like")) work_where.remove("toptassigneese:like");
				work_where.put("fromassigneesid:like", ","+user.getUserId()+",");
				toWorkList= historyQueryUtil.getWorkEntitys(null, work_where, null, 1000, 1);
				if(toWorkList!=null && toWorkList.size()>0) {
					info.setCtab(toWorkList.get(0).getTasktab());
					if(!this.userAuthUtils.getFutureWork(sexeid)) {
						for(BpmHistoryEntity entity:toWorkList) {
							this.userAuthUtils.setWithdraw(info, bpmKey, entity.gettaskdefid());
						}
					}
				}
				HashMap<String, Object> temp_where=new HashMap<String, Object> ();
				temp_where.put("actdefid:=", info.getBpmKey());
				temp_where.put("taskdefid:=", "U0");
				List<BpmTaskConfigEntity> temp_lst=this.bpmTaskConfigService.getEntitys(null, temp_where, null, 1, 1);
				if(temp_lst==null || temp_lst.size()<1) {
					info.setCtab("tab1");
				}else {
					info.setCtab(temp_lst.get(0).getPrjtab());
				}
				
			}
		}
		info.setcTaskId(cTaskId);
		info.setcTaskName(cTaskName);
	}
	
	
	/**
	 * 获取流程下一个节点信息
	 */
	@Override
	public OptionInfo getNextTask(String bpmkey, IBpmProjectEntity entity, List editHistory, UserInfo user) {
		return passWorkFlow.getNextTask(bpmkey, entity, editHistory, user);
	}

	/**
	 * 项目签收代码
	 */
	@Override
	public BpmMessage signTask(OptionInfo oInfo, IBpmProjectEntity entity, UserInfo user) {
		return passWorkFlow.signTask(oInfo, entity, user);
	}

	/**
	 * 获取退回节点
	 */
	@Override
	public OptionInfo getBackTask(String bpmkey, IBpmProjectEntity entity, List editHistory, UserInfo user) {
		return backWorkFlow.getBackTask(bpmkey, entity, editHistory, user);
	}

	/**
	 * 流程退回实现
	 */
	@Override
	public BpmMessage sendBaskTask(OptionInfo oInfo, IBpmProjectEntity entity, UserInfo user) {
		return this.backWorkFlow.sendBackTask(oInfo, entity, user);
	}
	
	/**
	 * 流程跳转实现
	 */
	@Override
	public OptionInfo getSkipTask(String definedid, IBpmProjectEntity entity, List editHistory, UserInfo user) {
		return skipWorkFlow.getSkipTask(definedid, entity, editHistory, user);
	}


	@Override
	public BpmMessage skipTask(OptionInfo oInfo, IBpmProjectEntity entity, UserInfo user) {
		return this.skipWorkFlow.skipTask(oInfo, entity, user);
	}

	/**
	 * 用户退件操作
	 */
	@Override
	public BpmMessage disposal(OptionInfo oInfo, IBpmProjectEntity entity, UserInfo user) {
		return this.disposeWorkFlow.dispose(oInfo, entity, user);
	}
	
	/**
	 * 用户自定义一次退件操作
	 */
	@Override
	public BpmMessage userDispose(OptionInfo oInfo, IBpmProjectEntity entity, UserInfo user) {
		return this.disposeWorkFlow.userDispose(oInfo, entity, user);
	}


	@Override
	public BpmMessage easter(OptionInfo optInfo, IBpmProjectEntity entity, UserInfo user) {
		return this.disposeWorkFlow.easter(optInfo, entity, user);
	}

	
	/**
	 * 流程保存操作
	 */
	@Override
	public BpmMessage processSave(OptionInfo oInfo, IBpmProjectEntity entity, UserInfo user) {
		String sexeid=oInfo.getSexeid();
		String prjid=entity.getId();
		String bpmKey=oInfo.getbpmkey();
		BpmMessage message=new BpmMessage();
		if("".equals(prjid) || prjid==null) {
			message.setStatus(false);
			message.setMessage("主键不能为空");
			return message;
		}
		//流程还没有启动处理方式
		if(sexeid==null ||
				"".equals(sexeid.trim()) 
				|| "null".equals(sexeid)) {
			HashMap<String,Object> work_where=new HashMap<String,Object>();
			work_where.put("sbussinessid:=",prjid);
			List<BpmHistoryEntity>toWorkList= historyQueryUtil.getWorkEntitys(null, work_where, null, 1000, 1);
			if(toWorkList==null || toWorkList.size()<1) {
				BpmHistoryEntity newh=this.historyEditUtl.CreateHistory(null, bpmKey, user, null, entity);
				newh.settaskdefname("草稿");
				newh.setfromtaskdefname("");
				newh.setNexttask("");
				newh.sethistorystatus("21");
				newh.setSread("1");
				newh.setoptresult("草稿");
				String tsassignees=","+user.getUserId()+","+user.getUserName()+",";
				newh.setToptassigneese(tsassignees);
				//这里不需要时效计算
				historyDao.add(newh);
			}else {
				BpmHistoryEntity oldw=toWorkList.get(0);
				if(user.isSuperAdmin()) {
					oldw.setsbusiness(entity.getProjectname());
					this.historyDao.update(oldw);
				}else {
					String toptusr=oldw.getToptassigneese();
					if(toptusr!=null && toptusr.contains(user.getUserId())) {
						oldw.setsbusiness(entity.getProjectname());
						this.historyDao.update(oldw);
					}else {
						message.setStatus(false);
						message.setMessage("没有项目权限，请与项目管理者联系");
						return message;
					}
				}
				
			}
		}else {
			HashMap<String,Object> work_where=new HashMap<String,Object>();
			work_where.put("sexeid:=", oInfo.getSexeid());
			//检查校验是否是超级管理员
			if(!user.isSuperAdmin()) {
				work_where.put("toptassigneese:like",user.getUserId());
			}
			List<BpmHistoryEntity>toWorkList= historyQueryUtil.getWorkEntitys(null, work_where, null, 1000, 1);
			//检查项目是否拥有权限
			if(toWorkList==null || toWorkList.size()<1) {
				message.setStatus(false);
				message.setMessage("没有项目审核的权限");
				return message;
			}
			
			List<BpmHistoryEntity> lst=oInfo.getEditHistory();
			if(lst==null || lst.size()<1) {
				lst=toWorkList;
			}else {
				for(BpmHistoryEntity ihistory:lst) {
					this.historyDao.update(ihistory);
				}
			}
			message.setStatus(true);
		}
		return message;
	}
}
